"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GameMgr = void 0;
const Config_1 = require("../Config");
const Player_1 = require("./core/Player");
const GameUtils_1 = __importDefault(require("./GameUtils"));
const HandlerMgr_1 = require("./HandlerMgr");
const Room_1 = require("../hall/Room");
const ManualMgr_1 = require("./ManualMgr");
const Logger_1 = __importDefault(require("../utils/Logger"));
const MapCreator_1 = __importDefault(require("./MapCreator"));
class GameMgr {
    constructor(room, users) {
        this.arr_small_borns = [GameUtils_1.default.getPointId(-2.0, 12.0), GameUtils_1.default.getPointId(-9.5, -7.0), GameUtils_1.default.getPointId(11.0, -4.0)];
        this.manual = new ManualMgr_1.ManualMgr();
        this.handlerMgr = new HandlerMgr_1.HandlerMgr(this);
        this.arr_players = new Array;
        this.map_point = new Map();
        this.second = 0;
        this.turnPlayer = null; //当前回合的玩家
        this.room = room;
        let arr_points = MapCreator_1.default.getArrPoints(this);
        for (let point of arr_points) {
            this.map_point.set(point.id, point);
        }
        // 玩家落点周围地形是空
        for (let i = 0; i < this.arr_small_borns.length; i++) {
            let point = this.map_point.get(this.arr_small_borns[i]);
            point.terrain = 0;
            let arround = GameUtils_1.default.getArrPointsAround(this, point);
            for (let point of arround) {
                point.terrain = 0;
            }
        }
        // 地图数据给客户端
        let arr_pointObjs = new Array();
        for (let point of arr_points) {
            arr_pointObjs.push(point.toObj());
        }
        // 初始化玩家
        for (let i = 0; i < users.length; i++) {
            this.arr_players.push(new Player_1.Player(this, users[i], this.arr_small_borns[i]));
        }
        //提前指点1号玩家是当前回合
        this.turnPlayer = this.arr_players[0];
        //先让客户端跳转到游戏场景
        let obj = GameUtils_1.default.getObj("gameReady", {}, false, false);
        this.sendBroadcast(obj);
        //发送玩家和地图数据
        setTimeout(() => {
            if (room.state == Room_1.RoomState.CLOSE)
                return;
            this.init(arr_pointObjs);
        }, 200);
        //正式开始游戏，开始计时
        setTimeout(() => {
            if (room.state == Room_1.RoomState.CLOSE)
                return;
            let obj = GameUtils_1.default.getObj("gameStart");
            this.sendBroadcast(obj);
            //后手补偿
            if (!Config_1.Config.DEBUG) {
            }
            //第一个玩家开始
            if (this.arr_players[0].is_death) {
                this.turnPlayer = this.arr_players[1];
            }
            else {
                this.turnPlayer = this.arr_players[0];
            }
            this.turnPlayer.turnStart();
            let obj1 = GameUtils_1.default.getObj("switchTurnPlay", { "username": this.turnPlayer.username });
            this.sendBroadcast(obj1);
            this.startTurnTimer();
        }, 4000);
    }
    /** 内存释放 */
    gc() {
        this.room = null;
        this.manual = null;
        this.handlerMgr = null;
        for (let point of this.map_point.values()) {
            point.gc();
        }
        this.map_point = null;
        this.arr_players.forEach(player => { player.gc(); });
        this.turnPlayer = null;
        clearInterval(this.interval_update);
        clearInterval(this.interval_turn);
    }
    init(arr_pointObjs) {
        //地图数据
        let obj_points = GameUtils_1.default.getObj("init_map", { "pointList": arr_pointObjs }, true, false);
        this.sendBroadcast(obj_points, false);
        //玩家数据
        let obj_users;
        if (Config_1.Config.DEBUG) {
            obj_users = GameUtils_1.default.getObj("init_players", { "playerList": [this.arr_players[0].toObj()] });
        }
        else {
            obj_users = GameUtils_1.default.getObj("init_players", { "playerList": [this.arr_players[0].toObj(), this.arr_players[1].toObj(), this.arr_players[2].toObj()] });
        }
        this.sendBroadcast(obj_users);
    }
    /**
     * 通知玩家的唯一通道
     * is_log 服务端是否打印日志
     * is_record 是否需要记录，时间更新，棋谱不需要记录
     */
    sendBroadcast(obj, is_log = true, is_record = true) {
        var _a;
        if (is_log) {
            Logger_1.default.log("send room message:", obj);
        }
        let json = JSON.stringify(obj);
        this.arr_players.forEach(player => {
            var _a;
            (_a = player.connection) === null || _a === void 0 ? void 0 : _a.sendText(json);
        });
        //记录操作
        if (is_record) {
            (_a = this.manual) === null || _a === void 0 ? void 0 : _a.record(json);
        }
    }
    /** 刷新视野可以放在客户端，服务端发送这个没有用 */
    sendRefreshView(player) {
        let obj = GameUtils_1.default.getObj("refreshView", null, true, false);
        let json = JSON.stringify(obj);
        player.connection.sendText(json);
    }
    reciveObj(obj, user) {
        switch (obj.method) {
            case "turnOver":
                this.switchTurnPlayer(obj.data);
                break;
            case "smallBornBig":
                this.handlerMgr.smallHandler.smallBornBig(obj.data, user.player);
                break;
            case "bigBornBig":
                this.handlerMgr.bigHandler.bigBornBig(obj.data, user.player);
                break;
            case "bigMove":
                this.handlerMgr.bigHandler.bigMove(obj.data, user.player);
                break;
            case "bigAttack":
                this.handlerMgr.bigHandler.bigAttack(obj.data, user.player);
                break;
            case "evolve":
                this.handlerMgr.bigHandler.evolve(obj.data, user.player);
                break;
            case "幽灵_move":
                this.handlerMgr.handler_幽灵.move(obj.data, user.player);
                break;
            case "恶灵_attack":
                this.handlerMgr.handler_恶灵.attack(obj.data, user.player);
                break;
            case "恶灵_possess":
                this.handlerMgr.handler_恶灵.possess(obj.data, user.player);
                break;
            case "炮台_impact":
                this.handlerMgr.handler_炮台.炮台_impact(obj.data, user.player);
                break;
            case "狙炮_aim":
                this.handlerMgr.handler_狙炮.狙炮_aim(obj.data, user.player);
                break;
            case "地灵_move":
                this.handlerMgr.handler_地灵.move(obj.data, user.player);
                break;
            case "地灵_抹平":
                this.handlerMgr.handler_地灵.地灵_抹平(obj.data, user.player);
                break;
            case "地灵_占据":
                this.handlerMgr.handler_地灵.地灵_占据(obj.data, user.player);
                break;
            case "精灵_move":
                this.handlerMgr.handler_精灵.move(obj.data, user.player);
                break;
            case "精灵_赐福":
                this.handlerMgr.handler_精灵.精灵_赐福(obj.data, user.player);
                break;
            case "精灵_庇护":
                this.handlerMgr.handler_精灵.精灵_庇护(obj.data, user.player);
                break;
            case "沙兵_move":
                this.handlerMgr.handler_沙兵.move(obj.data, user.player);
                break;
            case "沙兵_attack":
                this.handlerMgr.handler_沙兵.attack(obj.data, user.player);
                break;
            case "沙皇_move":
                this.handlerMgr.handler_沙皇.move(obj.data, user.player);
                break;
            case "沙皇_attack":
                this.handlerMgr.handler_沙皇.attack(obj.data, user.player);
                break;
            case "野猪_impact":
                this.handlerMgr.handler_野猪.impact(obj.data, user.player);
                break;
            case "野马_impact":
                this.handlerMgr.handler_野马.impact(obj.data, user.player);
                break;
            case "拳师_移动":
                this.handlerMgr.handler_拳师.拳师_移动(obj.data, user.player);
                break;
            case "拳师_怒威神拳":
                this.handlerMgr.handler_拳师.拳师_怒威神拳(obj.data, user.player);
                break;
            case "拳师_爆裂火拳":
                this.handlerMgr.handler_拳师.拳师_爆裂火拳(obj.data, user.player);
                break;
            case "灵阵_迷雾森林":
                this.handlerMgr.handler_灵阵.灵阵_迷雾森林(obj.data, user.player);
                break;
            case "灵阵_佛法慈悲":
                this.handlerMgr.handler_灵阵.灵阵_佛法慈悲(obj.data, user.player);
                break;
            case "灵阵_九曲黄河":
                this.handlerMgr.handler_灵阵.灵阵_九曲黄河(obj.data, user.player);
                break;
            case "灵阵_地狱杀伐":
                this.handlerMgr.handler_灵阵.灵阵_地狱杀伐(obj.data, user.player);
                break;
            case "天谕_明魂搜根":
                this.handlerMgr.handler_天谕.天谕_明魂搜根(obj.data, user.player);
                break;
            case "天谕_天眼传真":
                this.handlerMgr.handler_天谕.天谕_天眼传真(obj.data, user.player);
                break;
            case "天谕_神兵天降":
                this.handlerMgr.handler_天谕.天谕_神兵天降(obj.data, user.player);
                break;
            case "妖术_敲山震虎":
                this.handlerMgr.handler_妖术.妖术_敲山震虎(obj.data, user.player);
                break;
            case "妖术_绝命献祭":
                this.handlerMgr.handler_妖术.妖术_绝命献祭(obj.data, user.player);
                break;
            case "妖术_玄冰禁锢":
                this.handlerMgr.handler_妖术.妖术_玄冰禁锢(obj.data, user.player);
                break;
            case "妖术_瘟疫传播":
                this.handlerMgr.handler_妖术.妖术_瘟疫传播(obj.data, user.player);
                break;
            case "鼓舞_嗜血狂战":
                this.handlerMgr.handler_鼓舞.鼓舞_嗜血狂战(obj.data, user.player);
                break;
            case "鼓舞_乘风破浪":
                this.handlerMgr.handler_鼓舞.鼓舞_乘风破浪(obj.data, user.player);
                break;
            case "鼓舞_生生不息":
                this.handlerMgr.handler_鼓舞.鼓舞_生生不息(obj.data, user.player);
                break;
            case "鼓舞_常胜将军":
                this.handlerMgr.handler_鼓舞.鼓舞_常胜将军(obj.data, user.player);
                break;
            default: console.error("出现未知方法", obj.method);
        }
    }
    /** 检查存活 */
    checkAlive() {
        let num_alive = 3;
        let alive_player;
        this.arr_players.forEach(player => {
            if (player.is_death) {
                num_alive--;
            }
            else {
                alive_player = player;
            }
        });
        if (num_alive == 1) {
            this.gameOver(alive_player);
        }
    }
    /** 回合交换 */
    switchTurnPlayer(data) {
        if (this.room.state == Room_1.RoomState.CLOSE) {
            return;
        }
        //错误检测，如果当前回合不是你，你无法操作结束回合
        if (data.username != this.turnPlayer.username) {
            return;
        }
        //回合结束结算
        this.turnPlayer.turnOver();
        //找到下一个是谁的回合
        if (!Config_1.Config.DEBUG) {
            for (let i = 0; i < this.arr_players.length; i++) {
                if (this.turnPlayer == this.arr_players[i]) {
                    this.turnPlayer = this.arr_players[(i + 1) % this.arr_players.length];
                    if (this.turnPlayer.is_death || !this.turnPlayer.user.is_onLine) {
                        this.turnPlayer = this.arr_players[(i + 2) % this.arr_players.length];
                    }
                    break;
                }
            }
        }
        //回合开始结算
        this.turnPlayer.turnStart();
        //等把回合时间确定下来开启定时器
        this.startTurnTimer();
        //通知玩家回合切换
        let obj = GameUtils_1.default.getObj("switchTurnPlay", { "username": this.turnPlayer.username });
        this.sendBroadcast(obj);
    }
    /** 回合计时器 */
    startTurnTimer() {
        clearInterval(this.interval_turn);
        let turn_second = Config_1.Config.TIME_TURN;
        let time = GameUtils_1.default.secondToTime(turn_second);
        let obj = GameUtils_1.default.getObj("updateTurnTime", { "time": time }, true, false);
        this.sendBroadcast(obj, false, false);
        this.interval_turn = setInterval(() => {
            let time = GameUtils_1.default.secondToTime(turn_second);
            let obj = GameUtils_1.default.getObj("updateTurnTime", { "time": time }, true, false);
            this.sendBroadcast(obj, false, false);
            turn_second--;
            if (turn_second < 0) {
                this.switchTurnPlayer({ "username": this.turnPlayer.username });
                return;
            }
        }, 1000);
    }
    /** 游戏结束 */
    gameOver(winner) {
        Logger_1.default.log("游戏结束");
        let obj = GameUtils_1.default.getObj("gameOver", { "winner": winner.username }, true, true);
        this.sendBroadcast(obj, false);
        this.manual.saveManual();
        setTimeout(() => {
            this.room.closeRoom();
        }, 100);
    }
    /** 结算 */
    settlement() {
    }
}
exports.GameMgr = GameMgr;
